package com.hifar.test.equip.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hifar.fw.utils.id.IdUtils;
import com.hifar.fw.utils.lang.StringUtils;
import com.hifar.plat.AopOption.Dict;
import com.hifar.plat.AopOption.utils.oConvertUtils;
import com.hifar.plat.maindatasource.service.IMainDataSourceService;
import com.hifar.plat.officUtil.ExcelTemplateUtil;
import com.hifar.test.equip.util.CustomExcelExportUtil;
import com.hifar.sys.BusiResponse;
import com.hifar.sys.RequestConver;
import com.hifar.sys.SystemLoginUser;
import com.hifar.test.equip.mapper.HfResEquipMapper;
import com.hifar.test.equip.pojo.HfResEquip;
import com.hifar.test.equip.pojo.HfResEquipExportVo;
import com.hifar.test.equip.pojo.HfResEquipImportVo;
import com.hifar.test.equip.service.IHfResEquipService;
import com.hifar.test.task.pojo.VO.TaskMatchEquipVO;
import com.hifar.utils.ExcelImportUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 资源-设备 服务实现类
 * </p>
 *
 * @author wangkepeng
 * @since 2024-12-11 11:58:26
 */
@Service
public class HfResEquipServiceImpl extends ServiceImpl<HfResEquipMapper, HfResEquip> implements IHfResEquipService {

    @Autowired
    private IMainDataSourceService mainDataSourceService;

    @Override
    public BusiResponse exportExcel(Map<String, Object> pageInfo) {
        BusiResponse busiResponse = new BusiResponse();
        String ids = (String) pageInfo.get("ids");

        String operationType = (String) pageInfo.get("operationType");

        if (StringUtils.isNotBlank(operationType) && (operationType.equals("template"))) {
            CustomExcelExportUtil.exportExcelTemplate(busiResponse, HfResEquipImportVo.class, "设备基础信息导入模板", "设备基础信息", mainDataSourceService);
            return busiResponse;

        } else {
            QueryWrapper<HfResEquip> postParam = RequestConver.getPostParam(pageInfo);
            postParam.ne("del_flag", 1);
            
            // 添加权限过滤，与列表查询保持一致
            postParam.in("secret_level", SystemLoginUser.dataSecretSet);
            
            // 添加排序，与列表查询保持一致
            postParam.orderByAsc("row_sort");
            postParam.orderByDesc("create_time");
            
            // 处理搜索类型条件，与列表查询保持一致
            String searchType = StringUtils.trimNull((String) pageInfo.get("searchType"), "9");
            if (!"9".equals(searchType)) {
                // 当天开始时间戳
                long tm = com.hifar.fw.utils.lang.DateUtils.getDayStartLong(System.currentTimeMillis());
                // 第8天开始
                long weekTime = tm + 7 * 24 * 60 * 60 * 1000L;
                // 第31天开始
                long monthTime = tm + 30 * 24 * 60 * 60 * 1000L;
                
                if ("1".equals(searchType)) {  // 过期数据
                    postParam.gt("check_valid", new Date(0));
                    postParam.lt("check_valid", new Date(tm));
                } else if ("2".equals(searchType)) {  // 7天内过期
                    postParam.gt("check_valid", new Date(tm));
                    postParam.lt("check_valid", new Date(weekTime));
                } else if ("3".equals(searchType)) {  // 30天过期
                    postParam.gt("check_valid", new Date(tm));
                    postParam.lt("check_valid", new Date(monthTime));
                } else if ("4".equals(searchType)) {  // 有效设备
                    postParam.gt("check_valid", new Date(tm));
                }
            }
            
            // 处理设备类型和分类条件
            String equipTypeCode = StringUtils.trimNull((String) pageInfo.get("equipTypeCode"), "");
            if (!"".equals(equipTypeCode)) {
                postParam.eq("equip_type_code", equipTypeCode);
            }
            String classifyTypeCode = StringUtils.trimNull((String) pageInfo.get("classifyTypeCode"), "");
            if (!"".equals(classifyTypeCode)) {
                postParam.eq("classify_type_code", classifyTypeCode);
            }
            
            if (StringUtils.isNotBlank(ids)) {
                postParam.in("id", ids);
            }
            
            List<HfResEquip> dataList = this.list(postParam);
            List<HfResEquipExportVo> exportDataList = new ArrayList<>();
            for (HfResEquip bean : dataList) {
                HfResEquipExportVo exportVo = new HfResEquipExportVo();
                org.springframework.beans.BeanUtils.copyProperties(bean, exportVo);
                exportDataList.add(exportVo);
            }
            CustomExcelExportUtil.exportExcel(busiResponse, exportDataList, HfResEquipExportVo.class, "设备基础信息",
                    "设备基础信息", mainDataSourceService);
            return busiResponse;
        }

    }

    @Override
    public BusiResponse importExcel(MultipartFile file) throws Exception {
        if (Objects.isNull(file) || file.isEmpty()) {
            return BusiResponse.error("导入失败，原因未知！");
        }

        System.out.println("开始调用ExcelImportUtils.importExcelByColumnOrder...");
        // 使用按列顺序导入的方法
        List<HfResEquipImportVo> importExcel = ExcelImportUtils.importExcelByColumnOrder(file.getInputStream(),
                HfResEquipImportVo.class);
        System.out.println("ExcelImportUtils.importExcelByColumnOrder调用完成，返回数据条数: " + (importExcel != null ? importExcel.size() : "null"));
        List<HfResEquip> importExcelList = new ArrayList<>();

        if (importExcel == null || importExcel.isEmpty()) {
            return BusiResponse.error("导入数据为空！");
        }

        // 获取字典项映射 - 使用两步查询法
        Map<String, String> dictMapping = new HashMap<>();
        try {
            // 第一步：查询字典分类表获取ID
            String classifySql = "select id, dict_code from base_sys_dict_classify where " +
                    "dict_code in('hf_res_equip_use','equip_classify_type','hf_res_equip_type','hf_res_equip_status') and status<>99 and del_flag=0";
            List<Map<String, Object>> classifyList = mainDataSourceService.selectList(classifySql);
            
            if (!classifyList.isEmpty()) {
                // 构建分类ID列表
                String classifyIds = classifyList.stream()
                        .map(item -> StringUtils.trimNull(item.get("id")))
                        .collect(Collectors.joining(","));
                
                // 第二步：根据分类ID查询字典项
                String itemSql = "select c.dict_code, i.item_key, i.item_value from base_sys_dict_item i " +
                        "inner join base_sys_dict_classify c on i.dict_id = c.id " +
                        "where i.dict_id in(" + classifyIds + ") and i.status<>99 and i.del_flag=0";
                List<Map<String, Object>> dictList = mainDataSourceService.selectList(itemSql);
                
                dictMapping = dictList.stream().collect(Collectors.toMap(
                        item -> StringUtils.trimNull(item.get("dictCode")) + "#" + StringUtils.trimNull(item.get("itemValue")),
                        item -> StringUtils.trimNull(item.get("itemKey")), 
                        (o1, o2) -> o1));
            }
        } catch (Exception e) {
            System.out.println("获取字典项失败: " + e.getMessage());
        }

        for (int i = 0; i < importExcel.size(); i++) {
            HfResEquipImportVo bean = importExcel.get(i);

            // 进行字典项转换
            convertDictFields(bean, dictMapping);

            HfResEquip equipBean = new HfResEquip();
            equipBean.setId(IdUtils.uuid32());
            equipBean.setDelFlag("0");
            equipBean.setCreateTime(new java.util.Date());
            equipBean.setUpdateTime(new java.util.Date());

            BeanUtils.copyProperties(bean, equipBean);
            importExcelList.add(equipBean);
        }
        List<String> equipCodeList = importExcelList.stream()
                .map(HfResEquip::getEquipCode)
                .filter(code -> StringUtils.isNotBlank(code))
                .collect(Collectors.toList());
        List<HfResEquip> insertResEquipList = new ArrayList<>();
        List<HfResEquip> updateResEquipList = new ArrayList<>();

        if (!equipCodeList.isEmpty()) {
            QueryWrapper<HfResEquip> equipQueryWrapper = new QueryWrapper<>();
            equipQueryWrapper.lambda()
                    .in(HfResEquip::getEquipCode, equipCodeList);
            List<HfResEquip> existEquipList = this.list(equipQueryWrapper);
            Map<String, String> existEquipIdMap = existEquipList.stream()
                    .collect(
                            Collectors.toMap(
                                    HfResEquip::getEquipCode,
                                    HfResEquip::getId,
                                    (o1, o2) -> o2
                            )
                    );
            for (HfResEquip hfResEquip : importExcelList) {
                String equipCode = hfResEquip.getEquipCode();
                String equipId = existEquipIdMap.get(equipCode);
                if (Objects.isNull(equipId)) {
                    insertResEquipList.add(hfResEquip);
                } else {
                    hfResEquip.setId(equipId);
                    updateResEquipList.add(hfResEquip);
                }
            }
        } else {
            insertResEquipList.addAll(importExcelList);
        }

        // 分批处理插入数据
        if (!insertResEquipList.isEmpty()) {
            int batchSize = 100; // 每批处理100条数据
            for (int i = 0; i < insertResEquipList.size(); i += batchSize) {
                int endIndex = Math.min(i + batchSize, insertResEquipList.size());
                List<HfResEquip> batch = insertResEquipList.subList(i, endIndex);
                try {
                    this.saveBatchWithTransaction(batch);
                } catch (Exception e) {
                    System.err.println("插入数据失败，批次: " + (i / batchSize + 1) + ", 错误: " + e.getMessage());
                    throw e;
                }
            }
        }

        // 分批处理更新数据
        if (!updateResEquipList.isEmpty()) {
            int batchSize = 100; // 每批处理100条数据
            for (int i = 0; i < updateResEquipList.size(); i += batchSize) {
                int endIndex = Math.min(i + batchSize, updateResEquipList.size());
                List<HfResEquip> batch = updateResEquipList.subList(i, endIndex);
                
                try {
                    this.updateBatchWithTransaction(batch);
                } catch (Exception e) {
                    System.err.println("更新数据失败，批次: " + (i / batchSize + 1) + ", 错误: " + e.getMessage());
                    throw e;
                }
            }
        }
        return BusiResponse.ok("导入成功！");
    }

    /**
     * 带事务的批量插入方法
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void saveBatchWithTransaction(List<HfResEquip> batch) {
        this.saveBatch(batch);
    }

    /**
     * 带事务的批量更新方法
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void updateBatchWithTransaction(List<HfResEquip> batch) {
        this.updateBatchById(batch);
    }

    public static String removeSuffix(String input) {
        // 检查字符串是否以 ".0" 结尾
        if (input != null && input.endsWith(".0")) {
            // 去掉 ".0" 后缀
            return input.substring(0, input.length() - 2);
        }
        // 如果没有 ".0" 后缀，直接返回原字符串
        return input;
    }

    @Override
    public List<TaskMatchEquipVO> matchEquipList() {
        return baseMapper.selectMatchEquipList();
    }
    
    /**
     * 转换字典项字段
     */
    private void convertDictFields(HfResEquipImportVo bean, Map<String, String> dictMapping) {
        try {
            // 设备类型转换
            if (StringUtils.isNotBlank(bean.getEquipTypeCode())) {
                String dictKey = "hf_res_equip_type#" + bean.getEquipTypeCode();
                String itemKey = dictMapping.get(dictKey);
                if (StringUtils.isNotBlank(itemKey)) {
                    bean.setEquipTypeCode(itemKey);
                }
            }
            
            // 设备分类转换
            if (StringUtils.isNotBlank(bean.getClassifyTypeCode())) {
                String dictKey = "equip_classify_type#" + bean.getClassifyTypeCode();
                String itemKey = dictMapping.get(dictKey);
                if (StringUtils.isNotBlank(itemKey)) {
                    bean.setClassifyTypeCode(itemKey);
                }
            }
            
            // 设备用途转换
            if (StringUtils.isNotBlank(bean.getEquipUse())) {
                String dictKey = "hf_res_equip_use#" + bean.getEquipUse();
                String itemKey = dictMapping.get(dictKey);
                if (StringUtils.isNotBlank(itemKey)) {
                    bean.setEquipUse(itemKey);
                }
            }
            
            // 设备状态转换
            if (StringUtils.isNotBlank(bean.getStatus())) {
                String dictKey = "hf_res_equip_status#" + bean.getStatus();
                String itemKey = dictMapping.get(dictKey);
                if (StringUtils.isNotBlank(itemKey)) {
                    bean.setStatus(itemKey);
                }
            }
        } catch (Exception e) {
            System.out.println("字典项转换失败: " + e.getMessage());
        }
    }
}
